import axios from "axios";
import moment from "moment";
import cacheUtil from "@/utils/cacheUtil";
import {store} from "@/stores";
import {routerPush} from "@/router";
import useRouteStore from "@/stores/admin/useRouteStore";
import useUserStore from "@/stores/admin/useUserStore";

export let isRelogin = { show: false };
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 对应国际化资源文件后缀
axios.defaults.headers['Content-Language'] = 'zh_CN'
// 创建axios实例
const service = axios.create({
    // axios中请求配置有baseURL选项，表示请求URL公共部分
    baseURL: import.meta.env.VITE_APP_BASE_API,
    // 超时
    timeout: 9999999999
})


/**
 * 请求拦截
 */
service.interceptors.request.use((config) => {
    // 是否需要设置 token
    const isToken = (config.headers || {}).isToken === false
    // 是否需要防止数据重复提交
    const isRepeatSubmit = (config.headers || {}).repeatSubmit === false

    const {authorization} = storeToRefs(useRouteStore(store));
    if (authorization && config && config.headers) {
        typeof config.headers.set === 'function' && config.headers.set('Authorization',authorization?.value)
    }
    if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
        const requestObj = {
            url: config.url,
            data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
            time: new Date().getTime()
        }
        const sessionObj = cacheUtil.session.get('sessionObj')
        if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
            cacheUtil.session.set('sessionObj', requestObj)
        } else {
            const s_url = sessionObj.url;                // 请求地址
            const s_data = sessionObj.data;              // 请求数据
            const s_time = sessionObj.time;              // 请求时间
            const interval = 1000;                       // 间隔时间(ms)，小于此时间视为重复提交
            if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
                const message = '数据正在处理，请勿重复提交';
                console.warn(`[${s_url}]: ` + message)
                return Promise.reject(new Error(message))
            } else {
                cacheUtil.session.set('sessionObj', requestObj)
            }
        }
    }
    return config
}, (error) => {
    naive.notification.error({
        title: "网络请求错误",
        description: `From ${import.meta.env.VITE_APP_BASE_API}`,
        meta: moment().format('YYYY-MM-DD'),
        content: () =>
            `${typeof error.message === "string" ? error.message : JSON.stringify(error.message)}`
        ,
        duration: 5000,
        keepAliveOnHover: true
    })
})

/**
 * 响应拦截
 */
service.interceptors.response.use((response) => {
        const res = response.data;
        const message = res.message || "系统未知错误，请反馈给管理员";
        // 二进制数据则直接返回
        if (response.request.responseType ===  'blob' || response.request.responseType ===  'arraybuffer') {
            return response
        }

        if (res.status !== 200) {
            switch (res.status) {
                case 5005:
                    useUserStore(store).$reset()
                    // systemStore(store).removeAllTabs()
                    // systemStore(store).resetBreadMenuList()
                    cacheUtil.session.clear()
                    let path = useRoute().path;
                    if (path.indexOf("admin") > -1){
                        routerPush("adminLogin")
                        naive.message.warning(res.message)
                    }else {
                        naive.message.warning("登录失效，请重新登录")
                    }
                    break;
                case 1088:
                    naive.notification.warning({
                        title: "警告",
                        // description: `From ${import.meta.env.DEV ? devBaseURL : prodBaseURL}`,
                        meta: moment().format('YYYY-MM-DD'),
                        content: () => h("span",`${typeof message === "string" ? message : JSON.stringify(res.message)}`),
                        duration: 5000,
                        keepAliveOnHover: true
                    })
                    break;
                default:
                    naive.notification.error({
                        title: "网络请求错误",
                        // description: `From ${import.meta.env.DEV ? devBaseURL : prodBaseURL}`,
                        meta: moment().format('YYYY-MM-DD'),
                        content: () => h("span",`${typeof message === "string" ? message : JSON.stringify(res.message)}`),
                        duration: 5000,
                        keepAliveOnHover: true
                    })
            }
            return Promise.reject(res);
        } else {
            return  Promise.resolve(response)
        }
    },
    (error) => {
        /* 响应拦截失败的情况 */
        naive.notification.error({
            title: "请求响应错误",
            // description: `From ${import.meta.env.DEV ? devBaseURL : prodBaseURL}`,
            meta: moment().format('YYYY-MM-DD'),
            content: () => `${typeof error.message === "string" ? error.message : JSON.stringify(error.message)}`,
            duration: 5000,
            keepAliveOnHover: true
        })
        return Promise.reject(error);
    }
);

/**
 * 封装请求 get
 */
const get = (url,params) =>{
    return new Promise((resolve, reject) => {
        service.get(url, {
            params: params
        }).then(res  => {
            const status = res.data.status;
            if (status === 200){
                resolve(res.data);
            }else {
                reject(res.data);
            }
        }).catch(err => {
                reject(err)
        })
    });
}
const post = (url,params) =>{
    return new Promise((resolve, reject) =>{
        service.post(url,params).then(res => {
            const status = res.data.status;
            if (status === 200){
                resolve(res.data);
            }else {
                reject(res.data);
            }
        }).catch(err => {
            reject(err);
        })
    })
}
const put = (url,params) =>{
    return new Promise((resolve, reject) =>{
        service.put(url,params).then(res => {
            const status = res.data.status;
            if (status === 200){
                resolve(res.data);
            }else {
                reject(res.data);
            }
        }).catch(err => {
            reject(err);
        })
    })
}
const deleted = (url,params) =>{
    return new Promise((resolve, reject) =>{
        service.delete(url,params).then(res => {
            const status = res.data.status;
            if (status === 200){
                resolve(res.data);
            }else {
                reject(res.data);
            }
        }).catch(err => {
            reject(err);
        })
    })
}
let downloadLoadingInstance;
// 通用下载方法
function download(url, params, filename, config) {
    // downloadLoadingInstance = ElLoading.service({ text: "正在下载数据，请稍候", background: "rgba(0, 0, 0, 0.7)", })
    // return service.post(url, params, {
    //     transformRequest: [(params) => { return tansParams(params) }],
    //     headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    //     responseType: 'blob',
    //     ...config
    // }).then(async (data) => {
    //     const isBlob = blobValidate(data);
    //     if (isBlob) {
    //         const blob = new Blob([data])
    //         saveAs(blob, filename)
    //     } else {
    //         const resText = await data.text();
    //         const rspObj = JSON.parse(resText);
    //         const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
    //         ElMessage.error(errMsg);
    //     }
    //     downloadLoadingInstance.close();
    // }).catch((r) => {
    //     console.error(r)
    //     ElMessage.error('下载文件出现错误，请联系管理员！')
    //     downloadLoadingInstance.close();
    // })
}



var down = function (url, params = {}, isSuccess = false, description, isLoading = false,isDown=true) {
    // isLoading ? emitter.emit('loading', true) : ''
    const onDownloadProgress = params.onDownloadProgress;
    params["onDownloadProgress"] = null;
    return new Promise((resolve, reject) => {
        service.post(url,
         params,
         {
             responseType: 'blob',
             onDownloadProgress
         }).then(resp => {
            // isLoading ? emitter.emit('loading', false) : ''
            let headers = resp.headers;
            let contentType = headers['content-type'];
            // 接口报错，下载失败
            if (contentType === 'application/json') {
                reject();
                return;
            }

            if (!resp.data) {
                return false;
            } else {
                const blob = new Blob([resp.data], {type: contentType});
                const contentDisposition = resp.headers['content-disposition'];
                let fileName = 'unknown';
                if (contentDisposition) {
                    fileName = window.decodeURIComponent(resp.headers['content-disposition'].split('=')[1]);
                }
                if(isDown){
                    downFile(blob, fileName);
                }
                resolve(resp);
            }
        })
         .catch(err => {
             reject(err);
         });
    });
};

/* 下载方法 */
var downFile = function (blob, fileName) {
    // 非IE下载
    if ('download' in document.createElement('a')) {
        let link = document.createElement('a');
        link.href = window.URL.createObjectURL(blob); // 创建下载的链接
        link.download = fileName; // 下载后文件名
        link.style.display = 'none';
        document.body.appendChild(link);
        link.click(); // 点击下载
        window.URL.revokeObjectURL(link.href); // 释放掉blob对象
        document.body.removeChild(link); // 下载完成移除元素
    } else {
        // IE10+下载
        window.navigator.msSaveBlob(blob, fileName);
    }
}

export default {
    service,
    get,post,put,deleted,download,down
}
